<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Documentation SimpleTest : le rapporteur de test</title>
<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
</head>
<body>
<div class="menu_back">
<div class="menu">
<a href="index.html">SimpleTest</a>
                |
                <a href="overview.html">Overview</a>
                |
                <a href="unit_test_documentation.html">Unit tester</a>
                |
                <a href="group_test_documentation.html">Group tests</a>
                |
                <a href="mock_objects_documentation.html">Mock objects</a>
                |
                <a href="partial_mocks_documentation.html">Partial mocks</a>
                |
                <a href="reporter_documentation.html">Reporting</a>
                |
                <a href="expectation_documentation.html">Expectations</a>
                |
                <a href="web_tester_documentation.html">Web tester</a>
                |
                <a href="form_testing_documentation.html">Testing forms</a>
                |
                <a href="authentication_documentation.html">Authentication</a>
                |
                <a href="browser_documentation.html">Scriptable browser</a>
</div>
</div>
<h1>Documentation sur le rapporteur de test</h1>
        This page...
        <ul>
<li>
            Afficher <a href="#html">les r&eacute;sultats en HTML</a>
        </li>
<li>
            Afficher et <a href="#autres">rapporter les r&eacute;sultats</a> dans d'autres formats
        </li>
<li>
            Utilis&eacute; <a href="#cli">SimpleTest depuis la ligne de commande</a>
        </li>
<li>
            <a href="#xml">Utiliser XML</a> pour des tests distants
        </li>
</ul>
<div class="content">
        
            <p>
                SimpleTest suit plut&ocirc;t plus que moins le mod&egrave;le MVC (Mod&egrave;le-Vue-Contr&ocirc;leur). Les classes "reporter" sont les vues et les mod&egrave;les sont vos sc&eacute;narios de test et leur hi&eacute;rarchie. Le contr&ocirc;leur est le plus souvent masqu&eacute; &agrave; l'utilisateur de SimpleTest &agrave; moins de vouloir changer la fa&ccedil;on dont les tests sont effectivement ex&eacute;cut&eacute;s, auquel cas il est possible de surcharger les objets "runner" (ceux de l'ex&eacute;cuteur) depuis l'int&eacute;rieur d'un sc&eacute;nario de test. Comme d'habitude avec MVC, le contr&ocirc;leur est plut&ocirc;t ind&eacute;fini et il existe d'autres endroits pour contr&ocirc;ler l'ex&eacute;cution des tests.
            </p>
        
        <p>
<a class="target" name="html">
<h2>Les r&eacute;sultats rapport&eacute;s au format HTML</h2>
</a>
</p>
            <p>
                L'affichage par d&eacute;faut est minimal &agrave; l'extr&ecirc;me. Il renvoie le succ&egrave;s ou l'&eacute;chec avec les barres conventionnelles - rouge et verte - et affichent une trace d'arborescence des groupes de test pour chaque assertion erron&eacute;e. Voici un tel &eacute;chec...
                <div class="demo">
                    <h1>File test</h1>
                    <span class="fail">Fail</span>: createnewfile-&gt;True assertion failed.<br>
                    <div style="padding: 8px; margin-top: 1em; background-color: red; color: white;">1/1 test cases complete.
                    <strong>0</strong> passes, <strong>1</strong> fails and <strong>0</strong> exceptions.</div>
                </div>
                Alors qu'ici tous les tests passent...
                <div class="demo">
                    <h1>File test</h1>
                    <div style="padding: 8px; margin-top: 1em; background-color: green; color: white;">1/1 test cases complete.
                    <strong>1</strong> passes, <strong>0</strong> fails and <strong>0</strong> exceptions.</div>
                </div>
                La bonne nouvelle, c'est qu'il existe pas mal de points dans la hi&eacute;rarchie de l'affichage pour cr&eacute;er des sous-classes.
            </p>
            <p>
                Pour l'affichage bas&eacute; sur des pages web, il y a la classe <span class="new_code">HtmlReporter</span> avec la signature suivante...
<pre>
class HtmlReporter extends SimpleReporter {
    public HtmlReporter($encoding) { ... }
    public makeDry(boolean $is_dry) { ... }
    public void paintHeader(string $test_name) { ... }
    public void sendNoCacheHeaders() { ... }
    public void paintFooter(string $test_name) { ... }
    public void paintGroupStart(string $test_name, integer $size) { ... }
    public void paintGroupEnd(string $test_name) { ... }
    public void paintCaseStart(string $test_name) { ... }
    public void paintCaseEnd(string $test_name) { ... }
    public void paintMethodStart(string $test_name) { ... }
    public void paintMethodEnd(string $test_name) { ... }
    public void paintFail(string $message) { ... }
    public void paintPass(string $message) { ... }
    public void paintError(string $message) { ... }
    public void paintException(string $message) { ... }
    public void paintMessage(string $message) { ... }
    public void paintFormattedMessage(string $message) { ... }
    protected string _getCss() { ... }
    public array getTestList() { ... }
    public integer getPassCount() { ... }
    public integer getFailCount() { ... }
    public integer getExceptionCount() { ... }
    public integer getTestCaseCount() { ... }
    public integer getTestCaseProgress() { ... }
}
</pre>
                Voici ce que certaines de ces m&eacute;thodes veulent dire. Premi&egrave;rement les m&eacute;thodes d'affichage que vous voudrez probablement surcharger...
                <ul class="api">
                    <li>
                        <span class="new_code">HtmlReporter(string $encoding)</span>
<br>
                        est le constructeur. Notez que le test unitaire initie le lien &agrave; l'affichage plut&ocirc;t que l'oppos&eacute;. L'affichage est principalement un receveur passif des &eacute;v&egrave;nements de tests. Cela permet d'adapter facilement l'affichage pour d'autres syst&egrave;mes en dehors des tests unitaires, tel le suivi de la charge de serveurs. L'"encoding" est le type d'encodage que vous souhaitez utiliser pour l'affichage du test. Pour pouvoir effectuer un rendu correct de la sortie de d&eacute;bogage quand on utilise le testeur web, il doit correspondre &agrave; l'encodage du site test&eacute;. Les cha&icirc;nes de caract&egrave;res disponibles sont indiqu&eacute;es dans la fonction PHP <a href="http://www.php.net/manual/fr/function.htmlentities.php">html_entities()</a>.
                    </li>
                    <li>
                        <span class="new_code">void paintHeader(string $test_name)</span>
<br>
                        est appel&eacute; une fois, au d&eacute;but du test quand l'&eacute;v&egrave;nement de d&eacute;marrage survient. Le premier &eacute;v&egrave;nement de d&eacute;marrage est souvent d&eacute;livr&eacute; par le groupe de tests du niveau le plus haut et donc c'est de l&agrave; que le <span class="new_code">$test_name</span> arrive. Il peint les titres de la page, CSS, la balise "body", etc. Il ne renvoie rien du tout (<span class="new_code">void</span>).
                    </li>
                    <li>
                        <span class="new_code">void paintFooter(string $test_name)</span>
<br>
                        est appel&eacute; &agrave; la toute fin du test pour fermer les balises ouvertes par l'ent&ecirc;te de la page. Par d&eacute;faut il affiche aussi la barre rouge ou verte et le d&eacute;compte final des r&eacute;sultats. En fait la fin des tests arrive quand l'&eacute;v&egrave;nement de fin de test arrive avec le m&ecirc;me nom que celui qui l'a initi&eacute; au m&ecirc;me niveau. Le nid des tests en quelque sorte. Fermer le dernier test finit l'affichage.
                    </li>
                    <li>
                        <span class="new_code">void paintMethodStart(string $test_name)</span>
<br>
                        est appel&eacute; au d&eacute;but de chaque m&eacute;thode de test. Normalement le nom vient de celui de la m&eacute;thode. Les autres &eacute;v&egrave;nements de d&eacute;part de test se comportent de la m&ecirc;me mani&egrave;re sauf que celui du groupe de tests indique au rapporteur le nombre de sc&eacute;narios de test qu'il contient. De la sorte le rapporteur peut afficher une barre de progr&egrave;s au fur et &agrave; mesure que l'ex&eacute;cuteur passe en revue les sc&eacute;narios de test.
                    </li>
                    <li>
                        <span class="new_code">void paintMethodEnd(string $test_name)</span>
<br>
                        cl&ocirc;t le test lanc&eacute; avec le m&ecirc;me nom.
                    </li>
                    <li>
                        <span class="new_code">void paintFail(string $message)</span>
<br>
                        peint un &eacute;chec. Par d&eacute;faut il ne fait qu'afficher le mot "fail", une trace d'arborescence affichant la position du test en cours et le message transmis par l'assertion.
                    </li>
                    <li>
                        <span class="new_code">void paintPass(string $message)</span>
<br>
                        ne fait rien, par d&eacute;faut.
                    </li>
                    <li>
                        <span class="new_code">string _getCss()</span>
<br>
                        renvoie les styles CSS sous la forme d'une cha&icirc;ne &agrave; l'attention de la m&eacute;thode d'ent&ecirc;tes d'une page. Des styles additionnels peuvent &ecirc;tre ajout&eacute;s ici si vous ne surchargez pas les ent&ecirc;tes de la page. Vous ne voudrez pas utiliser cette m&eacute;thode dans des ent&ecirc;tes d'une page surcharg&eacute;e si vous souhaitez inclure le feuille de style CSS d'origine.
                    </li>
                </ul>
                Il y a aussi des accesseurs pour aller chercher l'information sur l'&eacute;tat courant de la suite de test. Vous les utiliserez pour enrichir l'affichage...
                <ul class="api">
                    <li>
                        <span class="new_code">array getTestList()</span>
<br>
                        est la premi&egrave;re m&eacute;thode tr&egrave;s commode pour les sous-classes. Elle liste l'arborescence courante des tests sous la forme d'une liste de noms de tests. Le premier test -- celui le plus proche du coeur -- sera le premier dans la liste et la m&eacute;thode de test en cours sera la derni&egrave;re.
                    </li>
                    <li>
                        <span class="new_code">integer getPassCount()</span>
<br>
                        renvoie le nombre de succ&egrave;s atteint. Il est n&eacute;cessaire pour l'affichage &agrave; la fin.
                    </li>
                    <li>
                        <span class="new_code">integer getFailCount()</span>
<br>
                        renvoie de la m&ecirc;me mani&egrave;re le nombre d'&eacute;checs.
                    </li>
                    <li>
                        <span class="new_code">integer getExceptionCount()</span>
<br>
                        renvoie quant &agrave; lui le nombre d'erreurs.
                    </li>
                    <li>
                        <span class="new_code">integer getTestCaseCount()</span>
<br>
                        est le nombre total de sc&eacute;narios lors de l'ex&eacute;cution des tests. Il comprend aussi les tests group&eacute;s.
                    </li>
                    <li>
                        <span class="new_code">integer getTestCaseProgress()</span>
<br>
                        est le nombre de sc&eacute;narios r&eacute;alis&eacute;s jusqu'&agrave; pr&eacute;sent.
                    </li>
                </ul>
                Une modification simple : demander &agrave; l'HtmlReporter d'afficher aussi bien les succ&egrave;s que les &eacute;checs et les erreurs...
<pre>
<strong>class ShowPasses extends HtmlReporter {
    
    function paintPass($message) {
        parent::paintPass($message);
        print "&amp;&lt;span class=\"pass\"&gt;Pass&lt;/span&gt;: ";
        $breadcrumb = $this-&gt;getTestList();
        array_shift($breadcrumb);
        print implode("-&amp;gt;", $breadcrumb);
        print "-&amp;gt;$message&lt;br /&gt;\n";
    }
    
    function _getCss() {
        return parent::_getCss() . ' .pass { color: green; }';
    }
}</strong>
</pre>
            </p>
            <p>
                Une m&eacute;thode qui a beaucoup fait jaser reste la m&eacute;thode <span class="new_code">makeDry()</span>. Si vous lancez cette m&eacute;thode, sans param&egrave;tre, sur le rapporteur avant que la suite de test ne soit ex&eacute;cut&eacute;e alors aucune m&eacute;thode de test ne sera appel&eacute;e. Vous continuerez &agrave; avoir les &eacute;v&egrave;nements entrants et sortants des m&eacute;thodes et sc&eacute;narios de test, mais aucun succ&egrave;s ni &eacute;chec ou erreur, parce que le code de test ne sera pas ex&eacute;cut&eacute;.
            </p>
            <p>
                La raison ? Pour permettre un affichage complexe d'une IHM (ou GUI) qui permettrait la s&eacute;lection de sc&eacute;narios de test individuels. Afin de construire une liste de tests possibles, ils ont besoin d'un rapport sur la structure du test pour l'affichage, par exemple, d'une vue en arbre de la suite de test. Avec un rapporteur lanc&eacute; sur une ex&eacute;cution s&egrave;che qui ne renverrait que les &eacute;v&egrave;nements d'affichage, cela devient facilement r&eacute;alisable.
            </p>
        
        <p>
<a class="target" name="autre">
<h2>Etendre le rapporteur</h2>
</a>
</p>
            <p>
                Plut&ocirc;t que de modifier l'affichage existant, vous voudrez peut-&ecirc;tre produire une pr&eacute;sentation HTML compl&egrave;tement diff&eacute;rente, ou m&ecirc;me g&eacute;n&eacute;rer une version texte ou XML. Plut&ocirc;t que de surcharger chaque m&eacute;thode dans  <span class="new_code">HtmlReporter</span> nous pouvons nous rendre une &eacute;tape plus haut dans la hi&eacute;rarchie de classe vers <span class="new_code">SimpleReporter</span> dans le fichier source <em>simple_test.php</em>.
            </p>
            <p>
                Un affichage sans rien, un canevas vierge pour votre propre cr&eacute;ation, serait...
<pre>
<strong>require_once('simpletest/simple_test.php');</strong>

class MyDisplay extends SimpleReporter {<strong>
    </strong>
    function paintHeader($test_name) {
    }
    
    function paintFooter($test_name) {
    }
    
    function paintStart($test_name, $size) {<strong>
        parent::paintStart($test_name, $size);</strong>
    }
    
    function paintEnd($test_name, $size) {<strong>
        parent::paintEnd($test_name, $size);</strong>
    }
    
    function paintPass($message) {<strong>
        parent::paintPass($message);</strong>
    }
    
    function paintFail($message) {<strong>
        parent::paintFail($message);</strong>
    }
}
</pre>
                Aucune sortie ne viendrait de cette classe jusqu'&agrave; un ajout de votre part.
            </p>
        
        <p>
<a class="target" name="cli">
<h2>Le rapporteur en ligne de commande</h2>
</a>
</p>
            <p>
                SimpleTest est aussi livr&eacute; avec un rapporteur en ligne de commande, minime lui aussi. L'interface imite celle de JUnit, sauf qu'elle envoie les messages d'erreur au fur et &agrave; mesure de leur arriv&eacute;e. Pour utiliser le rapporteur en ligne de commande, il suffit de l'intervertir avec celui de la version HTML...
<pre>
&lt;?php
    require_once('simpletest/unit_tester.php');
    require_once('simpletest/reporter.php');

    $test = &amp;new GroupTest('File test');
    $test-&gt;addTestFile('tests/file_test.php');
    $test-&gt;run(<strong>new TextReporter()</strong>);
?&gt;
</pre>
                Et ensuite d'invoquer la suite de test &agrave; partir d'une ligne de commande...
<pre class="shell">
php file_test.php
</pre>
                Bien s&ucirc;r vous aurez besoin d'installer PHP en ligne de commande. Une suite de test qui passerait toutes ses assertions ressemble &agrave;...
<pre class="shell">
File test
OK
Test cases run: 1/1, Failures: 0, Exceptions: 0
</pre>
                Un &eacute;chec d&eacute;clenche un affichage comme...
<pre class="shell">
File test
1) True assertion failed.
	in createnewfile
FAILURES!!!
Test cases run: 1/1, Failures: 1, Exceptions: 0
</pre>
            </p>
            <p>
                Une des principales raisons pour utiliser une suite de test en ligne de commande tient dans l'utilisation possible du testeur avec un processus automatis&eacute;. Pour fonctionner comme il faut dans des scripts shell le script de test devrait renvoyer un code de sortie non-nul suite &agrave; un &eacute;chec. Si une suite de test &eacute;choue la valeur <span class="new_code">false</span> est renvoy&eacute;e par la m&eacute;thode <span class="new_code">SimpleTest::run()</span>. Nous pouvons utiliser ce r&eacute;sultat pour terminer le script avec la bonne valeur renvoy&eacute;e...
<pre>
&lt;?php
    require_once('simpletest/unit_tester.php');
    require_once('simpletest/reporter.php');

    $test = &amp;new GroupTest('File test');
    $test-&gt;addTestFile('tests/file_test.php');
    <strong>exit ($test-&gt;run(new TextReporter()) ? 0 : 1);</strong>
?&gt;
</pre>
                Bien s&ucirc;r l'objectif n'est pas de cr&eacute;er deux scripts de test, l'un en ligne de commande et l'autre pour un navigateur web, pour chaque suite de test. Le rapporteur en ligne de commande inclut une m&eacute;thode pour d&eacute;terminer l'environnement d'ex&eacute;cution...
<pre>
&lt;?php
    require_once('simpletest/unit_tester.php');
    require_once('simpletest/reporter.php');

    $test = &amp;new GroupTest('File test');
    $test-&gt;addTestFile('tests/file_test.php');
    <strong>if (TextReporter::inCli()) {</strong>
        exit ($test-&gt;run(new TextReporter()) ? 0 : 1);
    <strong>}</strong>
    $test-&gt;run(new HtmlReporter());
?&gt;
</pre>
                Il s'agit l&agrave; de la forme utilis&eacute;e par SimpleTest lui-m&ecirc;me.
            </p>
        
        <p>
<a class="target" name="xml">
<h2>Test distant</h2>
</a>
</p>
            <p>
                SimpleTest est livr&eacute; avec une classe <span class="new_code">XmlReporter</span> utilis&eacute;e pour de la communication interne. Lors de son ex&eacute;cution, le r&eacute;sultat ressemble &agrave;...
<pre class="shell">
&lt;?xml version="1.0"?&gt;
&lt;run&gt;
  &lt;group size="4"&gt;
    &lt;name&gt;Remote tests&lt;/name&gt;
    &lt;group size="4"&gt;
      &lt;name&gt;Visual test with 48 passes, 48 fails and 4 exceptions&lt;/name&gt;
      &lt;case&gt;
        &lt;name&gt;testofunittestcaseoutput&lt;/name&gt;
        &lt;test&gt;
          &lt;name&gt;testofresults&lt;/name&gt;
          &lt;pass&gt;This assertion passed&lt;/pass&gt;
          &lt;fail&gt;This assertion failed&lt;/fail&gt;
        &lt;/test&gt;
        &lt;test&gt;
          ...
        &lt;/test&gt;
      &lt;/case&gt;
    &lt;/group&gt;
  &lt;/group&gt;
&lt;/run&gt;
</pre>
                Vous pouvez utiliser ce format avec le parseur fourni dans SimpleTest lui-m&ecirc;me. Il s'agit de <span class="new_code">SimpleTestXmlParser</span> et se trouve <em>xml.php</em> &agrave; l'int&eacute;rieur du paquet SimpleTest...
<pre>
&lt;?php
    require_once('simpletest/xml.php');
    
    ...
    $parser = &amp;new SimpleTestXmlParser(new HtmlReporter());
    $parser-&gt;parse($test_output);
?&gt;
</pre>
                <span class="new_code">$test_output</span> devrait &ecirc;tre au format XML, &agrave; partir du rapporteur XML, et pourrait venir d'une ex&eacute;cution en ligne de commande d'un sc&eacute;nario de test.  Le parseur envoie des &eacute;v&egrave;nements au rapporteur exactement comme tout autre ex&eacute;cution de test. Il y a des occasions bizarres dans lesquelles c'est en fait tr&egrave;s utile.
            </p>
            <p>
                Un probl&egrave;me des tr&egrave;s grandes suites de test , c'est qu'elles peuvent venir &agrave; bout de la limite de m&eacute;moire par d&eacute;faut d'un process PHP - 8Mb. En pla&ccedil;ant la sortie des groupes de test dans du XML et leur ex&eacute;cution dans des process diff&eacute;rents, le r&eacute;sultat peut &ecirc;tre pars&eacute; &agrave; nouveau pour agr&eacute;ger les r&eacute;sultats avec moins d'impact sur le test au premier niveau.
            </p>
            <p>
                Parce que la sortie XML peut venir de n'importe o&ugrave;, &ccedil;a ouvre des possibilit&eacute;s d'agr&eacute;gation d'ex&eacute;cutions de test depuis des serveur distants. Un sc&eacute;nario de test pour le r&eacute;aliser existe d&eacute;j&agrave; &agrave; l'int&eacute;rieur du framework SimpleTest, mais il est encore exp&eacute;rimental...
<pre>
&lt;?php
    <strong>require_once('../remote.php');</strong>
    require_once('../reporter.php');
    
    $test_url = ...;
    $dry_url = ...;
    
    $test = &amp;new GroupTest('Remote tests');
    $test-&gt;addTestCase(<strong>new RemoteTestCase($test_url, $dry_url)</strong>);
    $test-&gt;run(new HtmlReporter());
?&gt;
</pre>
                <span class="new_code">RemoteTestCase</span> prend la localisation r&eacute;elle du lanceur de test, tout simplement un page web au format XML. Il prend aussi l'URL d'un rapporteur initi&eacute; pour effectuer une ex&eacute;cution s&egrave;che. Cette technique est employ&eacute;e pour que les progr&egrave;s soient correctement rapport&eacute;s vers le haut. <span class="new_code">RemoteTestCase</span> peut &ecirc;tre ajout&eacute; &agrave; une suite de test comme n'importe quel autre groupe de tests.
            </p>
        
    </div>
        References and related information...
        <ul>
<li>
            La page du projet SimpleTest sur <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
        </li>
<li>
            La page de t&eacute;l&eacute;chargement de SimpleTest sur <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
        </li>
<li>
            L'<a href="http://simpletest.sourceforge.net/">API pour d&eacute;veloppeur de SimpleTest</a> donne tous les d&eacute;tails sur les classes et les assertions disponibles.
        </li>
</ul>
<div class="menu_back">
<div class="menu">
<a href="index.html">SimpleTest</a>
                |
                <a href="overview.html">Overview</a>
                |
                <a href="unit_test_documentation.html">Unit tester</a>
                |
                <a href="group_test_documentation.html">Group tests</a>
                |
                <a href="mock_objects_documentation.html">Mock objects</a>
                |
                <a href="partial_mocks_documentation.html">Partial mocks</a>
                |
                <a href="reporter_documentation.html">Reporting</a>
                |
                <a href="expectation_documentation.html">Expectations</a>
                |
                <a href="web_tester_documentation.html">Web tester</a>
                |
                <a href="form_testing_documentation.html">Testing forms</a>
                |
                <a href="authentication_documentation.html">Authentication</a>
                |
                <a href="browser_documentation.html">Scriptable browser</a>
</div>
</div>
<div class="copyright">
            Copyright<br>Marcus Baker 2006
        </div>
</body>
</html>
